/*
 *     This file is part of Mobile GPS Logger.
 *
 *     Mobile GPS Logger is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Mobile GPS Logger is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License v3 for more details.
 *
 *     You should have received a copy of the GNU General Public License v3
 *     along with Mobile GPS Logger. If not, see <http://www.gnu.org/licenses/>.
 */


package cx.ath.skyflyer.gpslog.thread;

import cx.ath.skyflyer.gpslog.util.UnderflowException;
import cx.ath.skyflyer.gpslog.util.Queue;
import java.util.Enumeration;
import java.util.NoSuchElementException;
import java.util.Vector;

/**
 *
 * @author Ahti Legonkov
 */
public class ThreadPool implements Runnable {

    private ThreadPool() {
        for (int i = 0; i < 5; ++i) {
            threads.addElement(new Thread(this));
        }

        new Thread(this).start();
    }

    private static final ThreadPool instance = new ThreadPool();

    public static ThreadPool getInstance() {
        return instance;
    }

    public void destroy() {
        Enumeration e = threads.elements();
        while (e.hasMoreElements()) {
            ((Thread)e.nextElement()).interrupt();
        }
    }

    public void queueWorkItem(WorkItem item) {
        synchronized (globalQueue) {
            // put an item to the queue ...
            globalQueue.push(item);
            // ... and notify anyone wiating for an item that it's ok to
            // retrieve it now.
            globalQueue.notify();
        }
    }

    public void run() {
        while (true) {
            try {
                synchronized (globalQueue) {
                    if (globalQueue.isEmpty()) {
                        // if the queue is empty wait for an item to appear
                        globalQueue.wait();
                    }

                    WorkItem item = (WorkItem)globalQueue.pop();
                    item.execute();
                }
            }
            catch (InterruptedException ex) {
                break;
            }
            catch (NoSuchElementException ex) {
                // assert(false);
            }
        }
    }

    private final Queue globalQueue = new Queue();
    private final Vector threads = new Vector();
}
